using System;
using System.Collections.Generic;
using System.Text;

using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.ComponentModel;

namespace Athena.Tools
{
    public class GridTool : IVisualTool
    {
        public GridTool()
        {
            _bHasMenuItems = true;
            ToolManager.Instance.RegisterTool("Grid Tool", "Displays a grid ...", this);
        }

        public override ToolManager.Order Order
        {
            get
            {
                return ToolManager.Order.BACK;
            }
        }

        private float _gridSpaceX = 10f;

        [CategoryAttribute("Grid Attributes"), Description("Distance between horizontal grid lines.")]
        public float GridSpaceX
        {
            get { return _gridSpaceX; }
            set { _gridSpaceX = value; }
        }

        private float _gridSpaceY = 10f;

        [CategoryAttribute("Grid Attributes"), Description("Distance between vertical grid lines.")]
        public float GridSpaceY
        {
            get { return _gridSpaceY; }
            set { _gridSpaceY = value; }
        }

        private float _gridWidth = 0.5f;

        [CategoryAttribute("Grid Attributes"), Description("Tickness of the lines of the Grid.")]
        public float Thickness
        {
            get { return _gridWidth; }
            set { _gridWidth = value; }
        }

        private Color _oGridColor = Color.LightBlue;

        [CategoryAttribute("Grid Attributes"), Description("Color of the Grid.")]
        public Color GridColor
        {
            get { return _oGridColor; }
            set { _oGridColor = value; }
        }


        private bool _bDrawGrid;

        [Browsable(false)]
        public bool DrawGrid
        {
            get { return _bDrawGrid; }
            set { _bDrawGrid = value; }
        }



        public override void SetupToolStrip(ToolStrip oStrip)
        {

            ToolStripButton oButton = new ToolStripButton("&Grid");
            oButton.DisplayStyle = ToolStripItemDisplayStyle.Text;
            oButton.ToolTipText = "Enables / Disables the grid ... ";
            oButton.TextDirection = ToolStripTextDirection.Vertical90;
            oButton.CheckState = CheckState.Unchecked;
            oButton.Tag = CheckState.Unchecked;
            oButton.Click += new EventHandler(oButton_Click);

            ToolStripButton oProperty = new ToolStripButton("...");
            oProperty.ToolTipText = "Sets up the grid";
            oProperty.TextDirection = ToolStripTextDirection.Vertical90;
            oProperty.Click += new EventHandler(oProperty_Click);
            
            oStrip.Items.Add(oButton);
            oStrip.Items.Add(oProperty);
            
        }

        void oProperty_Click(object sender, EventArgs e)
        {
            try
            {
                ScriptingHost oHost = ToolManager.Instance.ScriptEngine;
                oHost.ExecuteCommand("tool.PropertyEditor.SelectedObject = tool.Tools['Grid Tool'].Tool");                
            }
            catch (Exception)
            {
            }
        }

        void oButton_Click(object sender, EventArgs e)
        {
            if (sender is ToolStripButton)
            {
                ToolStripButton oButton = (ToolStripButton)sender;
                if (oButton.CheckState == CheckState.Unchecked)
                {
                    oButton.CheckState = CheckState.Checked;
                    oButton.Tag = CheckState.Checked;
                    DrawGrid = true;
                    Utility.Refresh();
                }
                else
                {
                    oButton.CheckState = CheckState.Unchecked;
                    oButton.Tag = CheckState.Unchecked;
                    DrawGrid = false;
                    Utility.Refresh();
                }
            }
        }

        //private float _GridExtendX = 1500F;

        //[CategoryAttribute("Grid Attributes"), Description("The extend of the horizontal grid lines")]
        //public float GridExtendX
        //{
        //    get { return _GridExtendX; }
        //    set { _GridExtendX = value; }
        //}
        //private float _GridExtendY = 1500F;

        //[CategoryAttribute("Grid Attributes"), Description("The extend of the vertical grid lines")]
        //public float GridExtendY
        //{
        //    get { return _GridExtendY;  }
        //    set { _GridExtendY = value; }
        //}

        private float _fMatchParameter = 0.4F;

        [CategoryAttribute("Grid Attributes"), Description("Fudge Parameter between 0...1, specifying how close an object has to be to snap, to the grid line.")]
        public float MatchParameter
        {
            get { return _fMatchParameter; }
            set { _fMatchParameter = value; }
        }


        public override void PreRender(System.Drawing.Graphics g)
        {
            if (DrawGrid)
            {
                SolidBrush oBrush = new SolidBrush(_oGridColor);
                Pen oPen = new Pen(oBrush, _gridWidth);

                float _GridExtendX = CurrentModel.ModelDimensions.Width;
                float _GridExtendY = CurrentModel.ModelDimensions.Height;

                for (int i = 0; i < _GridExtendY / _gridSpaceX + 1; i++)
                {
                    g.DrawLine(oPen, 0f, (float)i * _gridSpaceX, _GridExtendX, (float)i * _gridSpaceX);
                }
                for (int j = 0; j < _GridExtendX / _gridSpaceY + 1; j++)
                {
                    g.DrawLine(oPen, (float)j * _gridSpaceY, 0f,  (float)j * _gridSpaceY, _GridExtendY);
                }
            }
        }

        public override void PostRender(System.Drawing.Graphics g)
        {
            
        }

        public PointF GetTopGridPointClosestTo(PointF point)
        {
            float fResultX = ((int)(point.X / _gridSpaceX)) * _gridSpaceX;
            float fResultY = ((int)(point.Y / _gridSpaceY)) * _gridSpaceY; 
            return new PointF(fResultX, fResultY);
        }
    }
}
